package com.sc.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Type;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;


public class TransformUtil {

	public static byte[] hexStringToByte(String hex) {
		int len = (hex.length() / 2);
		byte[] result = new byte[len];
		char[] achar = hex.toCharArray();
		for (int i = 0; i < len; i++) {
			int pos = i * 2;
			result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
		}
		return result;
	}
	
	private static byte toByte(char c) {
		byte b = (byte) "0123456789ABCDEF".indexOf(c);
		return b;
	}

	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;

		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}

		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}

		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;

		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}

			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}

			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}

	public static final String bytesToHexString(byte[] bArray) {
		StringBuffer sb = new StringBuffer(bArray.length);
		String sTemp;
		for (int i = 0; i < bArray.length; i++) {
			sTemp = Integer.toHexString(0xFF & bArray[i]);
			if (sTemp.length() < 2)
				sb.append(0);
			sb.append(sTemp.toUpperCase());
		}
		return sb.toString();
	}

	public static byte[] transformObjectToByteByJava(Object obj) {
		ByteArrayOutputStream baout = new ByteArrayOutputStream();
		ObjectOutputStream oout = null;
		try {
			oout = new ObjectOutputStream(baout);
			oout.writeObject(obj);
			oout.flush();
			oout.close();  
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(oout != null) {
					oout.close();
				}
				if(baout != null) {
					baout.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return baout.toByteArray();
	}
	
	public static Object transformByteToObjectByJava(byte[] bytes) {
		Object obj = null;
		ByteArrayInputStream bain = null;
		ObjectInputStream oin = null;
		try {
			bain = new ByteArrayInputStream(bytes);
			oin = new ObjectInputStream(bain);
			obj = oin.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(oin != null) {
					oin.close();
				}
				if(bain != null) {
					bain.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return obj;
	}
	
	public static byte[] mergeByteArray(byte[] first, byte[] second) {
		byte[] buf = new byte[first.length+second.length];
		System.arraycopy(first, 0, buf, 0, first.length);
		System.arraycopy(second, 0, buf, first.length, second.length);
		return buf;
	}
	
	public static byte[] getCRCByte(byte[] buf) {
		int crc = 0xFFFF; // initial value
		int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)

		for (int j = 0; j < buf.length; j++) {
			char b = (char)(buf[j]&0xFF);
			for (int i = 0; i < 8; i++) {
				boolean bit = ((b >> (7 - i) & 1) == 1);
				boolean c15 = ((crc >> 15 & 1) == 1);
				crc <<= 1;
				if (c15 ^ bit)
					crc ^= polynomial;
			}
		}

		crc &= 0xffff;
		byte g_cCRCH=(byte)(crc>>8);
		byte g_cCRCL=(byte)crc;
		byte[] bcrc = new byte[]{g_cCRCH, g_cCRCL};
		return bcrc;
	}
/*	public static byte[] transformObjectToByteByGson(Object obj) {
		try {
			Gson gson = new Gson();
			String str = gson.toJson(obj);
			return str.getBytes();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public static Object transformByteToObjectByGson(byte[] bytes, Type typeOfT) {
		try {
			Gson gson = new Gson();
			String str = new String(bytes);
			return gson.fromJson(str, typeOfT);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	*/
	public static byte[] transformObjectToByteByJ2GZ(Object obj) {
		ByteArrayOutputStream baout = new ByteArrayOutputStream();
		ObjectOutputStream oout = null;
		GZIPOutputStream gzipout = null;
		try {
			gzipout = new GZIPOutputStream(baout);
			oout = new ObjectOutputStream(gzipout);
			oout.writeObject(obj);
			oout.flush();
			oout.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(oout != null) {
					oout.close();
				}
				if(gzipout != null) {
					gzipout.close();
				}
				if(baout != null) {
					baout.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return baout.toByteArray();
	}
	
	public static Object transformByteToObjectByJ2GZ(byte[] bytes) {
		Object obj = null;
		ByteArrayInputStream bain = null;
		ObjectInputStream oin = null;
		GZIPInputStream gzipin = null;
		try {
			bain = new ByteArrayInputStream(bytes);
			gzipin = new GZIPInputStream(bain);
			oin = new ObjectInputStream(gzipin);
			obj = oin.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(oin != null) {
					oin.close();
				}
				if(gzipin != null) {
					gzipin.close();
				}
				if(bain != null) {
					bain.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return obj;
	}
}
